unitbox = new Class ({

    initialize: function(options) {
        this.id = options.id;
        this.class = options.class;
        this.group = '';
        this.value = options.value;
        this.type = options.type;
        this.x = options.x;
        this.y = options.y;
        this.width = options.width;
        this.height = options.height;

        this.domobj = $(this.id);
        this.domobj.setStyle('top', this.x);
        this.domobj.setStyle('left', this.y);
        this.domobj.setStyle('width', parseInt(options.width) + 'px');
        this.domobj.setStyle('height', parseInt(options.height) + 'px');

        this.domobj.makeDraggable({'container':currentSheetbox, 'grid':5, 'snap':5});
        
        sizer = $(this.id + '_sizer');
        
        this.domobj.makeResizable({'handle':sizer, 'grid':5, 'snap':5});

    },

    updateCoords: function() {
        var ub_data = new Array();
        ub_data['x'] = this.domobj.getStyle('top');
        ub_data['y'] = this.domobj.getStyle('left');

        if (this.type != 'expression') {
            // - (padding + border)
            ub_data['width'] = this.domobj.getCoordinates().width - 10;
            ub_data['height'] = this.domobj.getCoordinates().height - 10;
            // qui un giorno ridimensionamento anche della canvas
            /*if (this.canvasctx != undefined) {
                this.canvasctx.scale(this.canvasel.width - ub_data['width'], this.canvasel.height - ub_data['height']);
                this.canvasel.setAttribute('width', ub_data['width']);
                this.canvasel.setAttribute('height', ub_data['height']);
            }*/
        }
        
        if (this.x == ub_data['x'] && this.y == ub_data['y'] && this.width == ub_data['width'] && this.height && ub_data['height'])
            return;
        
        ub_data['unitbox_id'] = this.domobj.getProperty('id');
        ub_data['docbox'] = currentDocboxName;
        this.x = ub_data['x'];
        this.y = ub_data['y'];
        this.width = ub_data['width'];
        this.height = ub_data['height'];
        document.getElementById("unitbox_coords").innerHTML = "x:" + ub_data['x'] + " y:" + ub_data['y'];
        var request = new Ajax('updateunitbox', {method: 'post', data:Object.toQueryString(ub_data)});
        request.request();
    },
    
    groupByClass: function() {
        var els = $ES('.sheetbox div.' + this.class);
        var i = 0;
        var top = parseInt(this.x) + this.domobj.getCoordinates().height + 1;
        for (; i < els.length; i++) {
            el = els[i];
            if (el.id != this.id) {
                var ub = getUnitboxFromId(el.id);
                ub.domobj.setStyle('top', top);
                ub.domobj.setStyle('left', this.y);
                ub.updateCoords();
                top = parseInt(ub.x) + ub.domobj.getCoordinates().height + 1;
            }
        }
    },
    
    groupByType: function() {
        var top = parseInt(this.x) + this.domobj.getCoordinates().height + 1;
        var type = this.type + 's';
        for (id in unitboxes[type]) {
            el = unitboxes[type][id];
            if (el.id != this.id) {
                el.domobj.setStyle('top', top);
                el.domobj.setStyle('left', this.y);
                el.updateCoords();
                top = parseInt(el.x) + el.domobj.getCoordinates().height + 1;
            }
        }
    },

    addtogroup: function(groupid) {
        this.group = groupid;
    }

});

unitboxnumber = unitbox.extend({
    
    initialize: function(options) {
        this.parent(options);
        this.value = this.value.round(2);
    }
});

unitboxexpression = unitbox.extend({
    
    initialize: function(options) {
        this.parent(options);
        this.callback = options.callback;
    },
    
    bindfunction: function() {
        for (f2map in expressionsmap[this.id]) {
            var idf2map = expressionsmap[this.id][f2map];
            var ef = unitboxes.expressions[idf2map].callback();
            document.getElementById(idf2map).innerHTML = ef;
            if ($type(ef) == 'number')
                eval(idf2map + " = " + ef + ";");
            else
                eval(idf2map + " = '" + ef + "';");
            
            unitboxes.expressions[idf2map].bindfunction();
        }
    }
});

unitboxstring = unitbox.extend({
    
    initialize: function(options) {
        this.parent(options);
    }
});

unitboxrange = unitbox.extend({
    
    from: 0,
    to: 0,
    step: 1,
    pointer: 0,
    
    initialize: function(options) {
        this.parent(options);
        this.from = options.from;
        this.to = options.to;
        this.step = options.step;
        this.range = new Array();
        this.createRange();
        //this.move2first(1);
        this.domobj.setText(this.from);
    },
    
    current: function() {
        return this.range[this.pointer];
    },
    
    next: function() {
        return this.range[++this.pointer];
    },
    
    reset: function() {
        this.pointer = 0;
    },
    
    createRange: function() {
        var i;

        for (i = this.from; i <= this.to; i += this.step) {
            this.range.push(i);
        }
    },
    
    decrement: function(bind) {
        if (this.pointer <= 0)
            return false;
        else
            this.pointer = this.pointer - 1;
    
        this.domobj.setText(this.current());
    
        eval(this.id + " = " + this.current() + ";"); 
    
        if (bind)
            this.bindrangefunction();
    },
    
    increment: function(bind) {
        if (this.pointer >= (this.range.length - 1))
            return false;
        else
            this.pointer += 1;
        
        this.domobj.setText(this.current());
    
        eval(this.id + " = " + this.current() + ";");
    
        if (bind)
            this.bindrangefunction();
    },
    
    move2last: function(bind) {
        this.pointer = this.range.length - 1;
        
        this.domobj.setText(this.current());
    
        eval(this.id + " = " + this.current() + ";");

        if (bind)
            this.bindrangefunction();
    },
    
    move2first: function(bind) {
        this.pointer = 0;
        
        this.domobj.setText(this.current());
    
        eval(this.id + " = " + this.current() + ";");
    
        if (bind)
            this.bindrangefunction();
    },
    
    bindrangefunction: function() {
        for (f in rangeexpressionsmap[this.id]) {
            var idf = rangeexpressionsmap[this.id][f];

            var ef = unitboxes.expressions[idf].callback();
            document.getElementById(idf).innerHTML = ef;
            if ($type(ef) == 'number')
                eval(idf + " = " + ef + ";");
            else
                eval(idf + " = '" + ef + "';");
            
            unitboxes.expressions[idf].bindfunction();
        }
    }
});

unitboxgraph = unitbox.extend({
    
    monitorized: [],
    canvasel: undefined,
    canvasctx: undefined,

    initialize: function(options) {
        this.parent(options);
        this.monitorized = new Array();
        this.canvasel = this.domobj.getElement('.sizer').remove();
        this.canvasel = this.domobj.getElement('canvas');
        if (this.canvasel.getContext) {
            this.canvasctx = this.canvasel.getContext('2d');
            this.canvasctx.beginPath();
            this.canvasctx.moveTo(0, 0);
            this.canvasctx.lineTo(0, this.canvasel.height);
            this.canvasctx.lineTo(this.canvasel.width, this.canvasel.height);
            this.canvasctx.stroke();

        }
    },

    monitor: function(ref) {
        this.monitorized.push(ref);
    }
});

g = new Class({

    initialize: function(options) {
        this.id = options.id;
        this.collection = new Array();
    },

    add: function(unitboxid) {
        this.collection.push(unitboxid);
    },

    highlight: function() {
        for (i = 0; i < this.collection.length; i++) {
            var ub = getUnitboxFromId(this.collection[i]).domobj;
            var ubcolor = ub.getStyle('background-color');

            var bgeffect = new Fx.Style(ub, 'background-color', {duration:500});

            bgeffect.start('#ffff00').chain(function(){
                this.start(ubcolor);
            });
        }
    },

    sum: function() {
        var sum = 0;
        for (i = 0; i < this.collection.length; i++) {
            var ubid = this.collection[i];
            var ub = getUnitboxFromId(ubid);
            
            switch (ub.type) {
                case 'number':
                    sum += Number(ub.value);
                break;
                case 'expression':
                    sum += Number(eval(ub.value + ';')).round(2);
                break;
            }
        }

        return sum;
    }
});

function getUnitboxFromId(id) {
    if (unitboxes.numbers[id] != undefined)
        return unitboxes.numbers[id];
    if (unitboxes.expressions[id] != undefined)
        return unitboxes.expressions[id];
    if (unitboxes.strings[id] != undefined)
        return unitboxes.strings[id];
    if (unitboxes.ranges[id] != undefined)
        return unitboxes.ranges[id];

    return false;
}